package com.thread.demo11;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 线程间通信，wait/notify
 * @author wdd  
 * @date 2019年10月31日
 */
public class WaitDemo2 {

	static boolean flag = true;
	static Object lock = new Object();
	
	public static void waits() throws InterruptedException{
		Object obj = new Object();
		Thread t1 = new Thread(()->{
			synchronized (obj) {
				for(int i=0;i<100;i++){
					System.out.println("t1="+i);
					if(i==10){
						try {
							obj.wait();
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
			}
		});
		
		Thread t2 = new Thread(()->{
			synchronized (obj) {
				for(int i=0;i<100;i++){
					System.out.println("t2="+i);
					if(i==10){
						obj.notifyAll();
					}
//					if(i==20){
//						try {
//							obj.wait();
//						} catch (Exception e) {
//							e.printStackTrace();
//						}
//					}
				}
			}
		});
		
		Thread t3 = new Thread(()->{
			synchronized (obj) {
				for(int i=0;i<100;i++){
					System.out.println("t3="+i);
					if(i==10){
						try {
							obj.wait();
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
			}
		});
		System.out.println("1111");
		new Thread(()->{
			try {
				Thread.sleep(1000);
			} catch (Exception e) {
				e.printStackTrace();
			}
			synchronized (obj) {
				System.out.println("1114");
				obj.notifyAll();
				System.out.println("1115");
			}
		}).start();
		synchronized (obj) {
			System.out.println("1112");
			obj.wait();
			System.out.println("1113");
		}
		System.out.println("1116");
		t1.start();
		t3.start();
		Thread.sleep(100);
		t2.start();
	}
	
	public static void main(String[] args) throws InterruptedException {
		Thread one = new Thread(new Wait(),"waitThread");
		one.start();
		Thread.sleep(1000);
		Thread two = new Thread(new Notify(),"notifyThread");
		two.start();
	}
	
	static class Wait implements Runnable{
		@Override
		public void run() {
			//获取锁
			synchronized (lock) {
				while(flag){
					System.out.println(Thread.currentThread()+";wait wait;"+new SimpleDateFormat("HH:mm:ss").format(new Date())+flag);
					try {
						//释放锁，当前线程放置对象的等待队列
						lock.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				System.out.println(Thread.currentThread()+";wait end;"+new SimpleDateFormat("HH:mm:ss").format(new Date())+flag);
			}
		}
	}
	
	static class Notify implements Runnable{
		@Override
		public void run() {
			synchronized (lock) {
				System.out.println(Thread.currentThread()+";lock Notify;"+new SimpleDateFormat("HH:mm:ss").format(new Date())+flag);
				//将等待队列中的线程全部移到同步队列
				lock.notifyAll();
				flag = false;
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			synchronized (lock) {
				System.out.println(Thread.currentThread()+";lock again;"+new SimpleDateFormat("HH:mm:ss").format(new Date())+flag);
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
}
